package com.ev.mes.service.impl;

import com.ev.apis.model.DsResultResponse;
import com.ev.common.enums.AuditStatusDict;
import com.ev.framework.config.ConstantForMES;
import com.ev.framework.il8n.MessageSourceHandler;
import com.ev.framework.utils.DateFormatUtil;
import com.ev.framework.utils.R;
import com.ev.framework.utils.ShiroUtils;
import com.ev.framework.utils.StringUtils;
import com.ev.mes.dao.MaterielPatrolDao;
import com.ev.mes.dao.MaterielPatrolItemDao;
import com.ev.mes.domain.MaterielPatrolDO;
import com.ev.mes.domain.MaterielPatrolItemDO;
import com.ev.mes.service.MaterielPatrolService;
import com.ev.mes.vo.MaterielPatrolItemPageParam;
import com.ev.mes.vo.MaterielPatrolPageParam;
import com.ev.mes.vo.MaterielPatrolSaveParam;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service
public class MaterielPatrolServiceImpl implements MaterielPatrolService {
    @Autowired
    private MaterielPatrolDao materielPatrolDao;
    @Autowired
    private MaterielPatrolItemDao patrolItemDao;
    @Autowired
    private MessageSourceHandler messageSourceHandler;

    @Override
    public MaterielPatrolDO get(Long id) {
        return materielPatrolDao.get(id);
    }

    @Override
    public List<MaterielPatrolDO> list(Map<String, Object> map) {
        return materielPatrolDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return materielPatrolDao.count(map);
    }

    @Override
    public int save(MaterielPatrolDO materielPatrol) {
        return materielPatrolDao.save(materielPatrol);
    }

    @Override
    public int update(MaterielPatrolDO materielPatrol) {
        return materielPatrolDao.update(materielPatrol);
    }

    @Override
    public int updateAll(MaterielPatrolDO materielPatrol) {
        return materielPatrolDao.updateAll(materielPatrol);
    }

    @Override
    public int remove(Long id) {
        return materielPatrolDao.remove(id);
    }

    @Override
    public int batchRemove(Long[] ids) {
        return materielPatrolDao.batchRemove(ids);
    }

    @Override
    public R saveAndVerify(MaterielPatrolSaveParam saveParam) {
        Map<String,Object> result = Maps.newHashMap();
        MaterielPatrolDO materielPatrolDO = saveParam.getMaterielPatrolDO();
        Long patrolId = materielPatrolDO.getId();
        List<MaterielPatrolItemDO> materielPatrolItemDOList = saveParam.getMaterielPatrolItemDOList();
        if (!(materielPatrolItemDOList != null && materielPatrolItemDOList.size() > 0)) {
            return R.error();
        }

        boolean isUpdate = patrolId != null;
        if (isUpdate) {
            MaterielPatrolDO materielPatrolOld = this.get(patrolId);
            // 已审核不能修改
            if (Objects.equals(materielPatrolOld.getStatus(), AuditStatusDict.OK_AUDIT.getId())) {
                return R.error(messageSourceHandler.getMessage("common.approved.update.disabled", null));
            }
            this.update(materielPatrolDO);

            List<Long> deleteItemIds = saveParam.getDeleteItemIds();
            // 删除明细
            if (deleteItemIds != null && deleteItemIds.size() > 0) {
                patrolItemDao.batchRemove(deleteItemIds.toArray(new Long[0]));
            }
            // 批量修改
            List<MaterielPatrolItemDO> batchUpdate = materielPatrolItemDOList
                    .stream()
                    .filter(e -> e.getId() != null)
                    .collect(Collectors.toList());
            // 批量增加
            Long finalPatrolId1 = patrolId;
            List<MaterielPatrolItemDO> batchSave = materielPatrolItemDOList
                    .stream()
                    .filter(e -> e.getId() == null)
                    .peek(e -> e.setPatrolId(finalPatrolId1))
                    .collect(Collectors.toList());
            if (batchUpdate.size() > 0) {
                patrolItemDao.batchUpdate(batchUpdate);
            }
            if (batchSave.size() > 0) {
                patrolItemDao.batchSave(batchSave);
            }
            result.put("id",patrolId);
            return R.ok(result);
        }
        // 设置编号
        materielPatrolDO.setCode(this.generateCode());
        materielPatrolDO.setStatus(AuditStatusDict.WAIT_AUDIT.getId());
        this.save(materielPatrolDO);

        patrolId = materielPatrolDO.getId();
        Long finalPatrolId = patrolId;
        materielPatrolItemDOList.forEach(e -> e.setPatrolId(finalPatrolId));
        patrolItemDao.batchSave(materielPatrolItemDOList);
        result.put("id",patrolId);
        return R.ok(result);
    }

    private String generateCode() {
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
        param.put("offset", 0);
        param.put("limit", 1);
        List<MaterielPatrolDO> list = this.list(param);
        return DateFormatUtil.getWorkOrderNo(ConstantForMES.PATROL_PREFIX, list.size() > 0 ? list.get(0).getCode() : null, 4);
    }

    @Override
    public Map<String, Object> getById(Long id) {
        Map<String, Object> patrolHead = materielPatrolDao.getById(id);
        Map<String, Object> result = Maps.newHashMap();
        if (patrolHead != null && patrolHead.size() > 0) {
            result.put("patrolHead", patrolHead);
            MaterielPatrolItemPageParam pageParam = new MaterielPatrolItemPageParam();
            pageParam.setPatrolId(id);
            List<Map<String, Object>> patrolBody = patrolItemDao.pageList(pageParam);
            result.put("patrolBody", patrolBody);
            return result;
        }
        return result;
    }

    @Override
    public Map<String, Object> pageList(MaterielPatrolPageParam pageParam) {
        Map<String, Object> result = Maps.newHashMap();
        List<Map<String, Object>> data = materielPatrolDao.pageList(pageParam);
        if (data.size() > 0) {
            Map<String, Object> pageCount = materielPatrolDao.pageCount(pageParam);
            int total = Integer.parseInt(pageCount.getOrDefault("total",0).toString());
            result.put("total",pageCount);
            result.put("data", new DsResultResponse(pageParam.getPageno(), pageParam.getPagesize(), total, data));
        }
        return result;
    }

    @Override
    public R audit(Long id) {
        MaterielPatrolDO materielPatrolDO = this.get(id);
        if (materielPatrolDO == null) {
            return R.error();
        }
        Long status = materielPatrolDO.getStatus();
        if (!Objects.equals(status,AuditStatusDict.WAIT_AUDIT.getId())){
            return R.error(messageSourceHandler.getMessage("common.massge.okAudit", null));
        }

        materielPatrolDO.setStatus(AuditStatusDict.OK_AUDIT.getId());
        materielPatrolDO.setAuditor(ShiroUtils.getUserId());
        materielPatrolDO.setAuditTime(new Date());
        this.updateAll(materielPatrolDO);

        return R.ok();
    }

    @Override
    public R reverseAudit(Long id) {
        MaterielPatrolDO materielPatrolDO = this.get(id);
        if (materielPatrolDO == null) {
            return R.error();
        }
        Long status = materielPatrolDO.getStatus();
        if (!Objects.equals(status,AuditStatusDict.OK_AUDIT.getId())){
            return R.error(messageSourceHandler.getMessage("common.massge.okWaitAudit", null));
        }
        materielPatrolDO.setStatus(AuditStatusDict.WAIT_AUDIT.getId());
        materielPatrolDO.setAuditor(null);
        materielPatrolDO.setAuditTime(null);
        this.updateAll(materielPatrolDO);

        return R.ok();
    }

    @Override
    public R batchDelete(List<Long> ids) {
        if (!(ids != null && ids.size() > 0)) {
            return R.error();
        }
        Map<String,Object> map = Maps.newHashMap();
        map.put("ids",ids);
        List<MaterielPatrolDO> list = this.list(map);
        Long status = AuditStatusDict.OK_AUDIT.getId();
        String collect = list.stream()
                .filter(e -> Objects.equals(status, e.getStatus()))
                .map(MaterielPatrolDO::getCode)
                .collect(Collectors.joining(","));
        if (StringUtils.isNoneEmpty(collect)){
            String [] args = {collect};
            return R.error(messageSourceHandler.getMessage("common.approved.delete.disabled.param", args));
        }
        Long[] deleteIds = ids.toArray(new Long[0]);
        this.batchRemove(deleteIds);
        patrolItemDao.batchRemoveByPatrolIds(deleteIds);

        return R.ok();
    }


}
